iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
0
Mobile Development

用 Flutter 開發一個 Android App 吧系列 第 26

用 Flutter 開發一個 Android App 吧 - Day 26. Provder 使用初體驗

  • 分享至 

  • xImage
  •  

本系列同步發表在 個人部落格,歡迎大家關注~

今天就開始來使用 Provider 來改動一下頁面囉~

首先要被我拿來實驗的頁面(們),就是登入/首頁的部份。
實驗的步驟則是參照官方文件教學 Simple app state management
官方範例是用一個簡單的購物及購物車 App,非常推薦可以閱讀它來理解狀態管理。

Lifting state up

這是官方教學的第一步驟,就是將分散在子孫節點的狀態(State),匯集在最上面的節點。
如下圖

對應 Gitme Reborn App 首先就是需要將帳戶資訊作集中管理。

lib/stores/account.dart

import 'package:flutter/foundation.dart';
import 'package:github/server.dart';
import 'package:gitme_reborn/services/github_api.dart';

class AccountModel extends ChangeNotifier {
  CurrentUser _user;
  List<Repository> _repos;
  List<Issue> _issues;

  CurrentUser get profile => _user;
  List<Repository> get repos => _repos;
  List<Issue> get issues => _issues;
  
  ...

  void updateUser(CurrentUser user) {
    _user = user;
    notifyListeners();
  }
  
  ...
}
  • 這邊先將使用者資訊(登入成功後撈取)、倉庫及議題資訊(切換到對應 Tab 時撈取),這三個帳戶資訊統一管理在 AccountModel 裡。
  • 繼承 ChangeNotifier 是必須的,用來使 AccountModel 有被其子孫節點註冊監聽的能力。

Provider

有了狀態(AccountModel)跟註冊監聽(ChangeNotifier),就剩下如何「提供通知」和「獲取狀態」。

而「提供通知」,照字面上就要有個提供者,也就是這套件的名稱 provider。
通常需要先知道是哪一部分的子孫節點們用到這些狀態,不過很大部份都會把 Provider 放在最上層,以提供整個 App 的狀態作管理。

day26-1.png

main.dart 裡,在 GitmeRebornApp 外面包一層 MultiProvider,在 providers 參數填入數值。

Consumer & Provider.of

最後就是「獲取狀態」,有兩種基本方式

  1. Provider.of

    MainPage.build 宣告 var account = Provider.of<AccountModel>(context);,之後在 MainPage 裡就能使用 account.xxx 來獲取狀態囉~

  2. Consumer

    參考 Commit 使用方式

    day26-2.png

小提醒:

  • RepoPageIssuePage 內基本上已經不用 StatefulWidget 了,所有的狀態都被我搬到 AccountModel 集中管理;不過改回 StatelessWidget 有些麻煩,所以就不改囉~
  • RepoPageIssuePage 內,會檢查狀態裡有沒有從 API 獲取過的資料,如果沒有或重新 Refresh 才會再次撈取
  • 記得使用 Provider 需要在 pubspec.yaml 裡加入 provider: ^3.1.0

--

成果

day26-3.gif


上一篇
用 Flutter 開發一個 Android App 吧 - Day 25. Flutter 中的狀態管理
下一篇
用 Flutter 開發一個 Android App 吧 - Day 27. ProfilePage & BadgeTab
系列文
用 Flutter 開發一個 Android App 吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言